﻿using Shop.Model.DB;
using Shop.Model.GoodsSku;
using Shop.RemoteModel.GoodsSku.Model;
using Shop.Repository;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Shop.Collect.lmpl
{
    internal class GoodsSkuCollect : IGoodsSkuCollect
    {
        private readonly IGoodsSkuRepository _Repository;

        public GoodsSkuCollect (IGoodsSkuRepository repository)
        {
            this._Repository = repository;
        }

        public long Add (SkuAdd add)
        {
            if (this._Repository.IsExist(c => c.GoodsId == add.GoodsId && c.SkuName == add.SkuName))
            {
                throw new ErrorException("shop.goods.sku.name.repeat");
            }
            return this._Repository.Add(add);
        }

        public long[] Clear (long goodsId, string[] specKey)
        {
            var sku = this._Repository.Gets(a => a.GoodsId == goodsId, a => new
            {
                a.SkuId,
                a.SpecsKey
            });
            if (sku.IsNull())
            {
                return null;
            }
            long[] skuId;
            if (!specKey.IsNull())
            {
                skuId = sku.Where(c => !specKey.Contains(c.SpecsKey)).Select(c => c.SkuId).ToArray();
                if (skuId.IsNull())
                {
                    return null;
                }
            }
            else
            {
                skuId = sku.ConvertAll(c => c.SkuId);
            }
            this._Repository.Delete(skuId);
            return skuId;
        }

        public DBGoodsSku Find (long goodsId, string specKey)
        {
            return this._Repository.Find(goodsId, specKey);
        }

        public DBGoodsSku Find (long skuId)
        {
            return this._Repository.Find(skuId);
        }

        public DBGoodsSku Get (long id)
        {
            return this._Repository.Get(id);
        }
        public SkuDatum[] Query (SkuQueryParam query, IBasicPage paging, out int count)
        {
            return this._Repository.Query(query, paging, out count);
        }
        public string GetSkuName (long id)
        {
            return this._Repository.Get(id, a => a.SkuName);
        }
        public Dictionary<long, string> GetSkuName (long[] ids)
        {
            if (ids.IsNull())
            {
                return new Dictionary<long, string>();
            }
            return this._Repository.Gets(ids, a => new
            {
                a.SkuId,
                a.SkuName
            }).ToDictionary(a => a.SkuId, a => a.SkuName);
        }
        public SkuDatum[] GetSkuDatums (long[] ids)
        {
            return this._Repository.GetSkuDatums(ids);
        }
        public DBGoodsSku[] GetsByGoodsId (long goodsId)
        {
            return this._Repository.GetsByGoodsId(goodsId);
        }
        public Result[] GetsByGoodsId<Result> (long goodsId) where Result : class, new()
        {
            return this._Repository.GetsByGoodsId<Result>(goodsId);
        }
        public Result[] GetsByGoodsId<Result> (long[] goodsId) where Result : class, new()
        {
            return this._Repository.GetsByGoodsId<Result>(goodsId);
        }
        public int GetSkuNum (long goodsId)
        {
            return this._Repository.Count(c => c.GoodsId == goodsId);
        }

        public long[] GetSkuId (long goodsId)
        {
            return this._Repository.Gets(a => a.GoodsId == goodsId, a => a.SkuId);
        }

        public bool Set (DBGoodsSku sku, SkuSet set)
        {
            return this._Repository.Set(sku, set);
        }
        public Dictionary<string, long> GetsBySpecKey (long goodsId)
        {
            return this._Repository.Gets(a => a.GoodsId == goodsId, a => new
            {
                a.SkuId,
                a.SpecsKey
            }).ToDictionary(a => a.SpecsKey, a => a.SkuId);
        }
        public long? Delete (long goodsId, string specKey)
        {
            long skuId = this._Repository.Get(a => a.GoodsId == goodsId && a.SpecsKey == specKey, a => a.SkuId);
            if (skuId == 0)
            {
                return null;
            }
            this._Repository.Delete(skuId);
            return skuId;
        }

        public long GetGoodsId (long skuId)
        {
            return this._Repository.Get(skuId, a => a.GoodsId);
        }

        public Result[] Gets<Result> (long[] ids) where Result : class
        {
            return this._Repository.Gets<Result>(ids);
        }

        public decimal GetMinPrice ( long[] skuId )
        {
           return _Repository.Min(c=>skuId.Contains(c.SkuId),c=>c.Price);
        }
    }
}
